package org.gd136.ce.script;

import java.io.BufferedReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.gd136.ce.manager.RM;
import org.gd136.ce.script.impl.CallScript;
import org.gd136.ce.script.impl.DelayScript;
import org.gd136.ce.script.impl.DialogScript;
import org.gd136.ce.script.impl.EndScript;
import org.gd136.ce.script.impl.EnterStageScript;
import org.gd136.ce.script.impl.JumpScript;
import org.gd136.ce.script.impl.OptionScript;
import org.gd136.ce.script.impl.PartSignScript;
import org.gd136.ce.script.impl.SelectEndScript;
import org.gd136.ce.script.impl.SelectScript;
import org.gd136.ce.script.impl.TxtScript;

import com.badlogic.gdx.files.FileHandle;

public class ScriptManager {
	public static final String //
	TAG_GAME_START = "GameStart"//
	, TAG_GAME_END = "GameEnd"//
	, TAG_NO_TAG = "NO_TAG_PART"//
	//
	;

	public static List<Script> scriptPool = new ArrayList<>();
	public static Script txtScript;
	/** <partName,scriptList>  */
	public static Map<String, List<Script>> pool;

	public static String currentPartName;
	public static List<Script> currentPart;
	public static List<Script> stack = new ArrayList<>();

	public static Script getCurrentScript() {
		if (stack.isEmpty()) {
			return null;
		}
		return stack.get(stack.size() - 1);
	}

	public static void nextScript() {
		Script current = getCurrentScript();
		if (current == null) {
			System.err.println("Script is done!!");
			return;
		}
		if (current.nextScript() != null) {
			stack.remove(stack.size() - 1);
			stack.add(current.nextScript());
		} else {
			stack.remove(stack.size() - 1);
			nextScript();
		}
	}

	public static void initScripts() {
		scriptPool.clear();
		scriptPool.add(new PartSignScript());
		scriptPool.add(new EndScript());
		scriptPool.add(new EnterStageScript());
		scriptPool.add(new DelayScript());
		scriptPool.add(new DialogScript());
		scriptPool.add(new CallScript());
		scriptPool.add(new JumpScript());
		scriptPool.add(new SelectScript());
		scriptPool.add(new SelectEndScript());
		scriptPool.add(new OptionScript());

		txtScript = new TxtScript();
	}

	public static void loadScript() {
		initScripts();

		pool = new HashMap<>();
		currentPart = new ArrayList<>();
		pool.put(TAG_NO_TAG, currentPart);

		FileHandle dir = RM.res("script");
		if (!dir.exists() || !dir.isDirectory()) {
			System.err.println("script 文件夹未找到!");
			return;
		}
		for (FileHandle file : dir.list(".spt")) {
			loadScript(file);
		}

		if (pool.containsKey(TAG_GAME_START)) {
			currentPartName = TAG_GAME_START;
			currentPart = pool.get(TAG_GAME_START);
			stack.add(currentPart.get(0));
		}

		if (!pool.get(TAG_NO_TAG).isEmpty()) {
			stack.add(pool.get(TAG_NO_TAG).get(0));
		}
	}

	public static void loadScript(FileHandle file) {
		BufferedReader br = null;
		try {
			br = new BufferedReader(file.reader("UTF-8"));
			String line;
			boolean isSkipLine = false;
			String fileName = file.name();
			int lineNum = 0;
			while ((line = br.readLine()) != null) {
				lineNum++;

				if (line.isEmpty()) {
					continue;
				}

				if (isSkipLine) {
					if (line.trim().endsWith("*/")) {
						isSkipLine = false;
					}
					continue;
				}
				if (line.startsWith("/*")) {
					isSkipLine = true;
					continue;
				}
				if (line.startsWith("//")) {
					continue;
				}
				if (line.startsWith("~")) {
					txtScript.readScript(line.substring(1));
					continue;
				}
				///
				loadScript(line.trim(), fileName, lineNum);
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (br != null) {
				try {
					br.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}

	public static Script loadScript(String scriptLine, String fileName,
			int lineNum) {
		Script result = null;
		for (Script script : scriptPool) {
			result = script.readScript(scriptLine);
			if (result != null) {
				result.setScriptSrc(fileName, lineNum);
				break;
			}
		}
		if (result == null) {
			result = txtScript.readScript(scriptLine);
		}

		return result;
	}

}
